package com.game.model;

import com.game.global.Const;
import com.game.global.CrashType;
import com.game.interfaces.Blast;
import com.game.interfaces.CollisionAble;
import com.game.interfaces.LifeCycle;
import com.game.main.GameContext;
import com.game.util.ImageUtil;
import com.game.util.PropertiesUtil;
import jdk.nashorn.internal.runtime.Context;

import java.awt.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by tjc on 2019-3-16.
 * 子弹类
 *
 * @auther: tjc
 * @Date: 2019-3-16
 */
public class Bullet extends Module implements CollisionAble, LifeCycle {

    //攻击力
    private int attack = 1;
    private Tank tk = null;

    private AtomicBoolean alive = new AtomicBoolean(false);
    private int bulletStep = 8;


    public Bullet(int x, int y, int direction, Tank tk) {
        this.localX = x;
        this.localY = y;
        this.SIZE_X = PropertiesUtil.loadInt("bullet.width");
        this.SIZE_Y = PropertiesUtil.loadInt("bullet.length");
        this.speed = PropertiesUtil.loadInt("bullet.speed");
        this.direction = direction;
        this.tk = tk;
    }

    @Override
    public void init() {
        alive.set(true);
    }


    @Override
    public void destroy() {
        alive.set(false);
        java.util.List<Blast> blastList = GameContext.getContext().blastList;

        BulletBlast blast = new BulletBlast(localX, localY);
        blastList.add(blast);
        blast.init();

    }

    @Override
    public Rectangle getRec() {
        return new Rectangle(localX, localY, SIZE_X, SIZE_Y);
    }

    @Override
    public int getCollisionType() {
        return CrashType.BULLET;
    }

    @Override
    public int getLocalX() {
        return localX;
    }

    @Override
    public int getLocalY() {
        return localY;
    }

    @Override
    public int getRight() {
        return this.getLocalX() + this.SIZE_X;
    }

    @Override
    public int getBottom() {
        return this.getLocalY() + this.SIZE_Y;
    }


    private void blockingEvent() {
        CollisionAble o = checkBlocking();
        handleBlocking(o);
    }

    private void handleBlocking(CollisionAble o) {
        if (o == null) return;
        if (o.getCollisionType() == CrashType.TANK) {
            Tank t = (Tank) o;

            t.destroy();
            GameContext context = GameContext.getContext();
            context.addPoints(100);
            this.destroy();
        } else if (o.getCollisionType() == CrashType.WALL) {
            Wall w = (Wall) o;
            w.destroy();
            this.destroy();
        } else if (o.getCollisionType() == CrashType.BORDER) {
            this.destroy();
        } else if (o.getCollisionType() == CrashType.HOME) {
            Home home = (Home) o;
            this.destroy();
            home.destroy();
        }
    }


    private CollisionAble checkBlocking() {
        //todo 待优化 每次移动都需要和所有墙壁判定是否碰撞
        if (localX < 0 || localX > Const.DEFAULT_PLAY_WIDTH || localY < 0 || localY > Const.DEFAULT_PLAY_LENGTH) {
            return new Border();
        }
        GameContext context = GameContext.getContext();
        for (Wall w : context.getWallList()) {
            if (checkCollision(w)) {
                return w;
            }
        }
        for (Tank t : context.getTankList()) {
            if (checkCollision(t) && t != this.tk) {
                return t;
            }
        }
        Home h = context.getHome();
        if (checkCollision(h)) {
            return h;
        }

        return null;
    }

    private boolean checkCollision(CollisionAble o) {
        return getRec().intersects(o.getRec());
    }

    /**
     * 移动函数
     *
     * @param direction
     */
    public void move(int direction) {
        switch (this.direction) {
            case Const.DIRECTION_UP:
                this.direction = direction;
                localY = localY - speed;
                break;
            case Const.DIRECTION_DOWN:
                this.direction = direction;
                localY = localY + speed;
                break;
            case Const.DIRECTION_LEFT:
                this.direction = direction;
                localX = localX - speed;
                break;
            case Const.DIRECTION_RIGHT:
                this.direction = direction;
                localX = localX + speed;
                break;
            default:
        }
    }

    /**
     * 画图函数
     *
     * @param g
     */
    public void draw(Graphics g) {
        //子弹击中目标
        if (!alive()) {
            return;
        }
        blockingEvent();
        move(direction);
        switch (this.direction) {
            case Const.DIRECTION_UP:
                g.drawImage(ImageUtil.bulletImages[0], localX, localY, SIZE_X, SIZE_Y, null);
                break;
            case Const.DIRECTION_DOWN:
                g.drawImage(ImageUtil.bulletImages[1], localX, localY, SIZE_X, SIZE_Y, null);
                break;
            case Const.DIRECTION_LEFT:
                g.drawImage(ImageUtil.bulletImages[2], localX, localY, SIZE_Y, SIZE_X, null);
                break;
            case Const.DIRECTION_RIGHT:
                g.drawImage(ImageUtil.bulletImages[3], localX, localY, SIZE_Y, SIZE_X, null);
                break;
            default:
        }
    }

    public boolean alive() {
        return alive.get();
    }
}
